package com.hmdp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hmdp.dto.Result;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Follow;
import com.hmdp.mapper.FollowMapper;
import com.hmdp.service.IFollowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IUserService;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 */
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private UserServiceImpl userServiceImpl;
    @Resource
    private IUserService userService;

    @Override
    public Result follow(Long followUserId, Boolean isFollow) {
//        被关注者的id,是否关注:布尔变量
        Long userId = UserHolder.getUser().getId();
//        获取当前关注者的id
        if(isFollow){
//            如果关注了这个用户
            Follow follow = new Follow();
//        创建一个 Follow 类的对象 follow，并初始化它。
            follow.setUserId(userId);
//            设置关注者的id,传入关注者的id
            follow.setFollowUserId(followUserId);
//            传入被关注者的id
           boolean isSuccess = save(follow);
//           保存关注信息到数据库,并且true/false

           if(isSuccess){
//               如果保存成功
               stringRedisTemplate.opsForSet().add("follow:"+userId,followUserId.toString());
//               redis里增加键为"follow:"+userId,值为被关注着的id
           }
        }else{
//            如果取消关注
            boolean isSuccess=remove(new QueryWrapper<Follow>()
//                    构建一个删除条件，删除 Follow 表中 user_id 为 userId 且 follow_user_id 为 followUserId 的记录。
//                    remove() 方法执行删除操作，返回值 isSuccess 为 true 表示删除成功，false 表示删除失败。
                    .eq("user_id", userId).eq("follow_user_id", followUserId));
//            查询关注者id和被关注者id,remove删除数据库关注关系
            if(isSuccess){
                stringRedisTemplate.opsForSet().remove("follow:"+userId,followUserId.toString());
//                从redis删除关注关系
            }
        }
        return Result.ok();
    }

    @Override
    public Result isFollow(Long followUserId) {
//        检查当前用户是否关注了指定用户
        Long userId = UserHolder.getUser().getId();
//        获取当前用户的id
        Integer count=query().eq("user_id", userId).eq("follow_user_id", followUserId).count();
//        通过 eq("user_id", userId) 和 eq("follow_user_id", followUserId) 查询数据库中是否存在记录，表示当前用户是否关注了
//        followUserId指定的用户。
        return Result.ok(count>0);
//        通过查询的条件 user_id 等于当前用户的ID，follow_user_id 等于指定的被关注用户ID，判断当前用户是否已经关注了该用户。如果查询
//        结果大于0，说明当前用户已经关注了指定用户。
    }

    @Override
    public Result followCommon(Long id) {
//        传入被关注着的id
        Long userId=UserHolder.getUser().getId();
//        获取当前用户的id
        Set<String> instersect =stringRedisTemplate.opsForSet().intersect("follow:"+userId,"follow:"+id);
//        在redis里使用交集intersect
        if(instersect==null||instersect.isEmpty()){
//            如果结果为空
            return Result.ok(Collections.emptyList());
//            返回空列表
        }
        List<Long> ids=instersect.stream().map(Long::valueOf).collect(Collectors.toList());
//        将共同关注的用户ID从String类型转换为Long类型,因为后面需要用 Long 类型的 ID 来查询用户信息。
        List<UserDTO> users=userService.listByIds(ids)
//                查找共同关注用户信息
                .stream() // 将获取到的用户信息转换为流
                .map(user-> BeanUtil.copyProperties(user,UserDTO.class))// 将实体对象复制到UserDTO对象中
                .collect(Collectors.toList()); // 收集成一个List返回
        //转化为UserDTO对象信息
        System.out.println("这是共同关注"+users);
        return Result.ok(users);
        // 返回包含共同关注用户信息的结果
    }
}
